package pjn;

import java.io.UnsupportedEncodingException;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;

public class JCLP {

    public static final int MAX_WORD_LENGTH = 30;
    public static final int MAX_LABEL_LENGTH = 10;
    public static final int MAX_FORMS = 40;
    public static final int SIZEOF_INT = 4;

    public interface ClpLibrary extends Library {
        ClpLibrary INSTANCE = (ClpLibrary) Native.loadLibrary("clp", ClpLibrary.class);

        void clp_init();

        String clp_ver();

        void clp_rec(byte[] inp, Memory out, IntByReference num);

        void clp_label(int id, Memory out);

        void clp_bform(int id, Memory out);

        void clp_forms(int id, Memory out);

        void clp_vec(int id, byte[] inp, Memory out, IntByReference num);

        int clp_pos(int id);
    }

    public static void init() {
        ClpLibrary.INSTANCE.clp_init();
    }

    public static String ver() {
        return ClpLibrary.INSTANCE.clp_ver();
    }

    public static int pos(int id) {
        return ClpLibrary.INSTANCE.clp_pos(id);
    }

    public static int[] rec(String form) {
        Memory out = new Memory(20 * SIZEOF_INT);
        IntByReference num = new IntByReference();
        byte bytes[];
        byte bytes_ended[];
        int ids[];

        try {
            bytes = form.getBytes("ISO-8859-2");
            bytes_ended = new byte[bytes.length + 1];
            for (int i = 0; i < bytes.length; ++i) {
                bytes_ended[i] = bytes[i];
            }
            bytes_ended[bytes.length] = 0;
            ClpLibrary.INSTANCE.clp_rec(bytes_ended, out, num);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.exit(1);
        }
        ids = new int[num.getValue()];
        out.read(0, ids, 0, ids.length);

        return ids;
    }

    public static String label(int id) {
        Memory out = new Memory(MAX_LABEL_LENGTH);

        ClpLibrary.INSTANCE.clp_label(id, out);

        return out.getString(0);
    }

    public static String bform(int id) {
        Memory out = new Memory(MAX_WORD_LENGTH * SIZEOF_INT);
        int strlen = 0;
        byte bytes[];
        String form = new String();

        ClpLibrary.INSTANCE.clp_bform(id, out);

        while (out.getByte(strlen) != 0) {
            strlen++;
        }
        bytes = new byte[MAX_WORD_LENGTH];
        out.read(0, bytes, 0, strlen);

        try {
            form = new String(bytes, "ISO-8859-2");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.exit(1);
        }

        return form;
    }

    public static String[] forms(int id) {
        Memory out = new Memory(MAX_FORMS * MAX_WORD_LENGTH * SIZEOF_INT);
        int strlen = 0;
        byte bytes[];
        String formsString = new String();
        String forms[], tmp[];

        ClpLibrary.INSTANCE.clp_forms(id, out);

        while (out.getByte(strlen) != 0) {
            strlen++;
        }
        bytes = new byte[MAX_FORMS * MAX_WORD_LENGTH];
        out.read(0, bytes, 0, strlen);

        try {
            formsString = new String(bytes, "ISO-8859-2");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.exit(1);
        }

        tmp = formsString.split(":");
        forms = new String[tmp.length - 1];
        System.arraycopy(tmp, 0, forms, 0, tmp.length - 1);

        return forms;
    }

    public static int[] vec(int id, String form) {
        Memory out = new Memory(50 * SIZEOF_INT);
        IntByReference num = new IntByReference();
        byte bytes[];
        byte bytes_ended[];
        int positions[];

        try {
            bytes = form.getBytes("ISO-8859-2");
            bytes_ended = new byte[bytes.length + 1];
            for (int i = 0; i < bytes.length; ++i) {
                bytes_ended[i] = bytes[i];
            }
            bytes_ended[bytes.length] = 0;
            ClpLibrary.INSTANCE.clp_vec(id, bytes_ended, out, num);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            System.exit(1);
        }
        positions = new int[num.getValue()];
        out.read(0, positions, 0, positions.length);

        return positions;
    }
}
